package com.zn.util;

import com.alibaba.fastjson.JSONObject;
import com.zn.entity.OptionTradingGoods;
import com.zn.service.MdInfoService;
import com.zn.vo.EtfMdInfo;
import com.zn.vo.Response;
import com.zn.vo.SocketJsonData;
import com.zn.web.rpc.MdRemoteCall;
import com.zn.websocket.group.ChannelGroups;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


@Component
@Order(1)
public class AsyncTask {
    private static final Logger LOGGER = LoggerFactory.getLogger(AsyncTask.class);
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Autowired
    private MdRemoteCall mdRemoteCall;
    @Autowired
    private MdInfoService mdInfoService;
    private ExecutorService pool = Executors.newCachedThreadPool();
    public volatile static LinkedList<Integer> points;

    @Async("executorPool")
    public void getEtfMdInfo() throws Exception{
        Map<Object, Object> mapTarget = redisTemplate.opsForHash().entries(Constant.TARGET_CODE_LIST);
        for (Object key : mapTarget.keySet()) {
            String tradingGoods = redisTemplate.opsForValue().get(Constant.TRADE_DATE_INFO+key.toString());
            OptionTradingGoods optionTradingGoods = JSONObject.parseObject(tradingGoods, OptionTradingGoods.class);
            String rep = redisTemplate.opsForValue().get(Constant.DATE_OF_TRANSACTION);
            Response response = JSONObject.parseObject(rep, Response.class);
            boolean tradingFlag = mdInfoService.checkTradingTime(optionTradingGoods.getTradingTime(), response);
            if (!tradingFlag){
                return;
            }
        }
        for (Object key : mapTarget.keySet()) {
            String etfMdInfoApiStr = mdRemoteCall.getEtfMdInfo(key.toString());
            String[] etfMdInfos = mdRemoteCall.subStringSinaData(etfMdInfoApiStr);
            if (etfMdInfos != null) {
                ////var hq_str_s_sh510050="50ETF,2.453,0.011,0.45,2836180,69702";
                EtfMdInfo etfMdInfo = new EtfMdInfo(etfMdInfos[0], etfMdInfos[1], etfMdInfos[3],etfMdInfos[2],  etfMdInfos[4], etfMdInfos[5]);
                Object jsonMd = JSONObject.toJSON(etfMdInfo);
                //主力合约列表
                SocketJsonData<EtfMdInfo> socketJsonData=new SocketJsonData<EtfMdInfo>(Constant.ETF,etfMdInfo);
                //深度行情json
                Object marketDataFieldToJson= JSONObject.toJSON(socketJsonData);
                //二进制推送 推送压缩后的包
                byte [] data= GZIPUtils.compress(marketDataFieldToJson.toString());
                ByteBuf byteBuf = Unpooled.buffer(data.length * 3);
                byteBuf.writeBytes(data);
                ChannelGroups.writeByEtf(new BinaryWebSocketFrame(byteBuf));
                String jieya=GZIPUtils.uncompressToString(data);
                LOGGER.info("getEtfMdInfo 解压后的数据包" + jieya);
                redisPut(Constant.TARGET_CODE_LIST, key.toString(), jsonMd.toString());
            }
        }
    }


    public void redisPut(String key,String id,String value){
        pool.execute(new Thread(() -> {
            redisTemplate.opsForHash().put(key, id, value);
        }));
    }

    @Async("executorPool")
    public void create(){
        LOGGER.info("启动造数方法模拟获取行情");
//        this.points=new LinkedList<Integer>();
//        while (true){
//            Integer num=(int)(Math.random()*10000);
//            if(this.points.size()>=60){
//                this.points.remove(0);
//                this.points.add(num);
//            }else {
//                this.points.add(num);
//                LOGGER.info("points.size():" + points.size());
//            }
//            try{Thread.sleep(1000);}catch(Exception ex){}
//        }

    }
    //每天的凌晨3点 16点执行一次
//    @Scheduled(cron="0/1 * * * * ?")
//    public void task() throws Exception{
//        LOGGER.info("启动造数方法模拟获取行情");
//        List<Object> tick=redisTemplate.opsForHash().values(Constant.MAIN_CONTRACT_KEY);
//        for(Object obj:tick){
//            CThostFtdcDepthMarketDataField stu=(CThostFtdcDepthMarketDataField) JSONUtil.JSONToObj(obj.toString(),
//                    CThostFtdcDepthMarketDataField.class);
////            String zipStr=GZIPUtils.compress(obj.toString());
//            //压缩的data
//            //主力合约列表
//            SocketJsonData<CThostFtdcDepthMarketDataField> socketJsonData=new SocketJsonData<CThostFtdcDepthMarketDataField>(Constant.TICK,stu);
//            //深度行情json
//            Object marketDataFieldToJson= JSONObject.toJSON(socketJsonData);
//            byte [] data=GZIPUtils.compress(marketDataFieldToJson.toString());
//            ByteBuf byteBuf = Unpooled.buffer(data.length * 3);
//            byteBuf.writeBytes(data);
//            ChannelGroups.broadcast(new BinaryWebSocketFrame(byteBuf));
//            System.err.println("数据流："+new BinaryWebSocketFrame(byteBuf).toString());
//            String jieya=GZIPUtils.uncompressToString(data);
//            System.err.println("解压后的数据包"+jieya);
////            ChannelGroups.broadcast(new BinaryWebSocketFrame(Unpooled.wrappedBuffer(obj.toString().getBytes())));
//        }
//    }
}
